<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <script>
    // Promise：ES6新出的一个对象，用于管理异步任务，解决回调地域问题
    // 怎么解决：用的是Promise的链式调用特征

    // 1.复习基础语法
    // 创建Promise对象
    // let p = new Promise((resolve, reject) => {
    //   // 异步任务-ajax/定时器计时器
    //   setTimeout(() => {
    //     // resolve('成功')
    //     reject('失败')
    //   }, 1000)//一秒后比ajax需要请求+响应总耗费事件（模拟）
    // })
    // 如何拿到Promise对象成功/失败的结果
    // resolve()-.then()里函数体代码执行
    // reject()-.catch()里函数体代码执行
    // p.then
    //   (res => {
    //     console.log(res)//拿到成功
    //   })
    // p.catch(err => {
    //   console.log(err)
    // })



    // 1.高级用法
    // 口诀:Promise对象.then（）在原地会有一个返回值，是一个全新的Promise对象
    //   let p1=p.then()
    // console.log(p===p1);//false不等于

    // 2.高级用法
    // 口诀:then（）里函数体非return，返回给下一个Promise对象使用

    // 情况1：return的是非Promise对象
    // let p1=p.then(res=>{//res成功
    //   return 100//特殊：return给P1（下一个Promise对象的then里使用）
    // })
    // p1.then(result=>{
    //   console.log(result);
    // })

    // 情况2：
    // return 的是一个新的Promise对象呢，替换then()函数默认在原地返回的那个全新Promise对象
    // 下一个then里拿到的是return的这个Promise对象里的resolve的结果
    // let p1=p.then(res=>{
    //   console.log(res);
    //   return new Promise((resolve,reject)=>{
    //     setTimeout(()=>{
    //       resolve('第二次')
    //     },2000)
    //   })
    // })
    // p1.then(result=>{
    // console.log(result);
    // })



    // 3.高级用法
    // 口诀:Promise对象.catch（）在原地会有一个返回值，是一个全新的Promise对象
    //  链式调用：每个函数里返回同样的一个对象，继续点调用内部的其他方法，一直点下去就是链式调用
    //  let p1=p.then().catch()
    //  console.log(p1===p);//false


    // 4.高级用法
    // catch()里return会返回到，下个一Promise对象的then里使用
    // 总结:无论then/catch里()里函数体的return，都会返回给下一个Promise的then里
    // let p1 = p.catch(err => {
    //   console.log(err)//失败
    //   return 3
    // })
    // p1.then(result => {
    //   console.log(result)//3
    // })

    // awaitTo技术
    // 为什么：因为await，只能默认取代then函数，只能拿到then的结果
    // 如果await后面Promise内报错，我们需要使用try+catch来进行捕获
    // 解决：我想把try+catch优化掉，让await可以提取到成功和失败的结果
    // 例如
    function myAxios () {
      let pA = new Promise((resolve, reject) => {
        // 异步任务-ajax/定时器计时器
        setTimeout(() => {
          // resolve('成功')
          reject('失败')
        }, 1000)//一秒后比ajax需要请求+响应总耗费事件（模拟）
      })
      return pA
    }
    // let pA = myAxios()
    // let pB = pA.then(res => {
    //   return res
    // }).catch(err => {
    //   return err//会返回给PB的then使用(pA的错误信息中转下去)
    // })
    // // pB.then(res => {
    // //   console.log(res)//失败
    // // })
    // async function myFn () {
    //   const res = await pB//await还是取代PB的then
    //   console.log(res)//失败
    // }
    // myFn()
    // 如果相判断类型的话
    let pA = myAxios()
    let pB = pA.then(res => {
      return [null, res]
    }).catch(err => {
      return [err, null]//会返回给PB的then使用(pA的错误信息中转下去)
    })
    // pB.then(res => {
    //   console.log(res)//失败
    // })
    async function myFn () {
      // 因为pB拿出来的就是上面的res和err，进行解构

      // 为何要加await？
      // await等待：等待后面用户信息保存vuex，在next()跳转页面，就能直接看到用户名
      // 如果不加，异步去请求，主线程代码先往下next()跳转页面，页面上没有名字，异步请求组数据就完成vuex值变量
      // 响应式更新所有使用vuex相关的变量  从没有名字 到有名字显示
      const [res, err] = await pB//await还是取代PB的then
      if (err) console.err(err)//如果err有值的话就证明是报错
      else console.log(res)//失败，成功的话
      // 如何区分res到底是成功的，还是失败的
      传对象或者数组
      // 1个变量位置无法区分时成功值/失败值，那么我在中站的地方传出一个数组
      // 数组的第一个位置错误信息,第二个位置正确信息
    }
    myFn()

  </script>
</body>

</html>